#!/home/wcaarls/compile/bin/python

import sys, random, archdesc, pisa, copy, time, lockdict

def create(results, noise=0.0, nr=1):
  while 1:
    alltypes = ["fc", "uniring", "bus"]
    #alltypes = ["bus"]
    allbandwidths = [5000000, 10000000, 100000000]
    #allbandwidths = [1000000, 2500000, 5000000, 10000000, 25000000, 50000000, 100000000, 250000000]
    #allbandwidths = [100000000]
    allcomponents = ["tm", "m24kc", "xl", "rc2", "rc4", "im132", "im66"]
    #allcomponents = ["tm", "xl"]
    #allcomponentbws = [1000000, 2500000, 5000000, 10000000, 25000000, 50000000, 100000000, 250000000]
    allcomponentbws = copy.deepcopy(allbandwidths)
    #allfrequencies = [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5]
    allfrequencies = [1.0]

    type = alltypes[random.randrange(0, len(alltypes))]
    bandwidth = allbandwidths[random.randrange(0, len(allbandwidths))]

    components = [archdesc.ComponentDesc("camera", 0, 0, allcomponentbws[random.randrange(0, len(allcomponentbws))])]

    for i in range(random.randrange(0, 5)):
      t = allcomponents[random.randrange(0, len(allcomponents))]
      b = allcomponentbws[random.randrange(0, len(allcomponentbws))]
      components.append(archdesc.ComponentDesc(t, 1.0, 0, b))
      
    # Make sure the design contains an ILP processor
    foundilp = False
    for c in components:
      if c.type == "tm" or c.type == "ss" or c.type == "m24kc":
        foundilp = True
    if not foundilp:
      continue

    a = archdesc.ArchDesc(type, bandwidth, components, 1, alltypes, allbandwidths, allcomponents, allcomponentbws, allfrequencies)
    m = archdesc.MapDesc(random.random(), random.random(), random.random(), random.random(), random.random())
    s = archdesc.SystemDesc(a, m)

    results.lock()
    if not s in results:
      results.unlock()
      s.evaluate(results, "robocup", 0, noise, nr)
      break
    else:
      results.unlock()

def variate(arch, results, noise=0.0, nr=1):
  variations = arch.vary()
  while 1:
    v = variations[random.randrange(0, len(variations))]
    
    results.lock()
    if not v in results:
      results.unlock()
      v.evaluate(results, "robocup", 0, noise, nr)
      break
    else:
      results.unlock()

def variate2(arch, results, noise=0.0, nr=1):
  while 1:
    v = arch.vary_random()
    
    results.lock()
    if not v in results:
      results.unlock()
      v.evaluate(results, "robocup", 0, noise, nr)
      break
    else:
      results.unlock()

def var(n, d):
  if random.random() < 0.5:
    return (1.0/d + (1.0-1.0/d)*random.random())*n
  else:
    return (1 + (d-1.0)*random.random()) * n

def output(arch, result):
  arch.OutputMatlab(result)

def uniquerows(archlist):
  return list(set(archlist))

# Seems to be the wrong way round!
def getpareto(archlist):
  archlist = uniquerows(archlist)
  paretolist = []
  for (a, r) in archlist:
    pareto = 1
    for (b, s) in archlist:
      if a != b and s[0] < r[0] and s[1] < r[1] and s[2] < r[2]:
        pareto = 0
        break
    if pareto:
      paretolist.append((a, r))
  return paretolist

if __name__ == "__main__":
  results = lockdict.lockdict()
  create(results)

  while 1:
    print results
    time.sleep(1)
    